﻿using System;
using UnityEngine;

namespace RootMotion.Demos
{
	// Token: 0x020000DF RID: 223
	public class CharacterThirdPerson : CharacterBase
	{
		// Token: 0x17000099 RID: 153
		// (get) Token: 0x06000675 RID: 1653 RVA: 0x0000629A File Offset: 0x0000449A
		// (set) Token: 0x06000676 RID: 1654 RVA: 0x000062A2 File Offset: 0x000044A2
		public bool onGround { get; set; }

		// Token: 0x06000677 RID: 1655 RVA: 0x0003A2AC File Offset: 0x000384AC
		public override void Start()
		{
			base.Start();
			this.animator = base.GetComponent<Animator>();
			if (this.animator == null)
			{
				this.animator = this.characterAnimation.GetComponent<Animator>();
			}
			this.wallNormal = Vector3.up;
			this.onGround = true;
			this.animState.onGround = true;
			if (this.cam != null)
			{
				this.cam.enabled = false;
			}
		}

		// Token: 0x06000678 RID: 1656 RVA: 0x000062AB File Offset: 0x000044AB
		public void OnAnimatorMove()
		{
			this.Move(this.animator.deltaPosition, this.animator.deltaRotation);
		}

		// Token: 0x06000679 RID: 1657 RVA: 0x000062C9 File Offset: 0x000044C9
		public override void Move(Vector3 deltaPosition, Quaternion deltaRotation)
		{
			this.fixedDeltaPosition += deltaPosition;
			this.fixedDeltaRotation *= deltaRotation;
		}

		// Token: 0x0600067A RID: 1658 RVA: 0x0003A328 File Offset: 0x00038528
		public void FixedUpdate()
		{
			if (this.animator != null && this.animator.updateMode == AnimatorUpdateMode.AnimatePhysics)
			{
				this.smoothPhysics = false;
				this.characterAnimation.smoothFollow = false;
			}
			this.r.interpolation = ((!this.smoothPhysics) ? RigidbodyInterpolation.None : RigidbodyInterpolation.Interpolate);
			this.characterAnimation.smoothFollow = this.smoothPhysics;
			this.MoveFixed(this.fixedDeltaPosition);
			this.fixedDeltaPosition = Vector3.zero;
			base.transform.rotation *= this.fixedDeltaRotation;
			this.fixedDeltaRotation = Quaternion.identity;
			this.Rotate();
			this.GroundCheck();
			if (this.userControl.state.move == Vector3.zero && this.groundDistance < this.airborneThreshold * 0.5f)
			{
				base.HighFriction();
			}
			else
			{
				base.ZeroFriction();
			}
			if (this.onGround)
			{
				this.animState.jump = this.Jump();
			}
			else
			{
				this.r.AddForce(Physics.gravity * this.gravityMultiplier - Physics.gravity);
			}
			base.ScaleCapsule((!this.userControl.state.crouch) ? 1f : this.crouchCapsuleScaleMlp);
			this.fixedFrame = true;
		}

		// Token: 0x0600067B RID: 1659 RVA: 0x0003A4A4 File Offset: 0x000386A4
		public virtual void Update()
		{
			this.animState.onGround = this.onGround;
			this.animState.moveDirection = this.GetMoveDirection();
			this.animState.yVelocity = this.r.velocity.y;
			this.animState.crouch = this.userControl.state.crouch;
			this.animState.isStrafing = (this.moveMode == CharacterThirdPerson.MoveMode.Strafe);
		}

		// Token: 0x0600067C RID: 1660 RVA: 0x0003A520 File Offset: 0x00038720
		public virtual void LateUpdate()
		{
			if (this.cam == null)
			{
				return;
			}
			this.cam.UpdateInput();
			if (!this.fixedFrame && this.r.interpolation == RigidbodyInterpolation.None)
			{
				return;
			}
			this.cam.UpdateTransform((this.r.interpolation != RigidbodyInterpolation.None) ? Time.deltaTime : Time.fixedDeltaTime);
			this.fixedFrame = false;
		}

		// Token: 0x0600067D RID: 1661 RVA: 0x0003A598 File Offset: 0x00038798
		public void MoveFixed(Vector3 deltaPosition)
		{
			this.WallRun();
			Vector3 vector = deltaPosition / Time.deltaTime;
			vector += new Vector3(this.platformVelocity.x, 0f, this.platformVelocity.z);
			if (this.onGround)
			{
				if (this.velocityToGroundTangentWeight > 0f)
				{
					Quaternion b = Quaternion.FromToRotation(base.transform.up, this.normal);
					vector = Quaternion.Lerp(Quaternion.identity, b, this.velocityToGroundTangentWeight) * vector;
				}
			}
			else
			{
				Vector3 b2 = new Vector3(this.userControl.state.move.x * this.airSpeed, 0f, this.userControl.state.move.z * this.airSpeed);
				vector = Vector3.Lerp(this.r.velocity, b2, Time.deltaTime * this.airControl);
			}
			if (this.onGround && Time.time > this.jumpEndTime)
			{
				this.r.velocity = this.r.velocity - base.transform.up * this.stickyForce * Time.deltaTime;
			}
			vector.y = Mathf.Clamp(this.r.velocity.y, this.r.velocity.y, (!this.onGround) ? this.r.velocity.y : this.maxVerticalVelocityOnGround);
			this.r.velocity = vector;
			float b3 = this.onGround ? base.GetSlopeDamper(-deltaPosition / Time.deltaTime, this.normal) : 1f;
			this.forwardMlp = Mathf.Lerp(this.forwardMlp, b3, Time.deltaTime * 5f);
		}

		// Token: 0x0600067E RID: 1662 RVA: 0x0003A7A0 File Offset: 0x000389A0
		public void WallRun()
		{
			bool flag = this.CanWallRun();
			if (this.wallRunWeight > 0f && !flag)
			{
				this.wallRunEndTime = Time.time;
			}
			if (Time.time < this.wallRunEndTime + 0.5f)
			{
				flag = false;
			}
			this.wallRunWeight = Mathf.MoveTowards(this.wallRunWeight, (!flag) ? 0f : 1f, Time.deltaTime * this.wallRunWeightSpeed);
			if (this.wallRunWeight <= 0f && this.lastWallRunWeight > 0f)
			{
				base.transform.rotation = Quaternion.LookRotation(new Vector3(base.transform.forward.x, 0f, base.transform.forward.z), Vector3.up);
				this.wallNormal = Vector3.up;
			}
			this.lastWallRunWeight = this.wallRunWeight;
			if (this.wallRunWeight <= 0f)
			{
				return;
			}
			if (this.onGround && this.r.velocity.y < 0f)
			{
				this.r.velocity = new Vector3(this.r.velocity.x, 0f, this.r.velocity.z);
			}
			Vector3 forward = base.transform.forward;
			forward.y = 0f;
			RaycastHit raycastHit = default(RaycastHit);
			raycastHit.normal = Vector3.up;
			Physics.Raycast((!this.onGround) ? this.capsule.bounds.center : base.transform.position, forward, out raycastHit, 3f, this.wallRunLayers);
			this.wallNormal = Vector3.Lerp(this.wallNormal, raycastHit.normal, Time.deltaTime * this.wallRunRotationSpeed);
			this.wallNormal = Vector3.RotateTowards(Vector3.up, this.wallNormal, this.wallRunMaxRotationAngle * 0.0174532924f, 0f);
			Vector3 forward2 = base.transform.forward;
			Vector3 vector = this.wallNormal;
			Vector3.OrthoNormalize(ref vector, ref forward2);
			base.transform.rotation = Quaternion.Slerp(Quaternion.LookRotation(forward, Vector3.up), Quaternion.LookRotation(forward2, this.wallNormal), this.wallRunWeight);
		}

		// Token: 0x0600067F RID: 1663 RVA: 0x0003AA20 File Offset: 0x00038C20
		public bool CanWallRun()
		{
			return Time.time >= this.jumpEndTime - 0.1f && Time.time <= this.jumpEndTime - 0.1f + this.wallRunMaxLength && this.r.velocity.y >= this.wallRunMinVelocityY && this.userControl.state.move.magnitude >= this.wallRunMinMoveMag;
		}

		// Token: 0x06000680 RID: 1664 RVA: 0x0003AAA8 File Offset: 0x00038CA8
		public Vector3 GetMoveDirection()
		{
			CharacterThirdPerson.MoveMode moveMode = this.moveMode;
			if (moveMode == CharacterThirdPerson.MoveMode.Directional)
			{
				this.moveDirection = Vector3.SmoothDamp(this.moveDirection, new Vector3(0f, 0f, this.userControl.state.move.magnitude), ref this.moveDirectionVelocity, this.smoothAccelerationTime);
				this.moveDirection = Vector3.MoveTowards(this.moveDirection, new Vector3(0f, 0f, this.userControl.state.move.magnitude), Time.deltaTime * this.linearAccelerationSpeed);
				return this.moveDirection * this.forwardMlp;
			}
			if (moveMode != CharacterThirdPerson.MoveMode.Strafe)
			{
				return Vector3.zero;
			}
			this.moveDirection = Vector3.SmoothDamp(this.moveDirection, this.userControl.state.move, ref this.moveDirectionVelocity, this.smoothAccelerationTime);
			this.moveDirection = Vector3.MoveTowards(this.moveDirection, this.userControl.state.move, Time.deltaTime * this.linearAccelerationSpeed);
			return base.transform.InverseTransformDirection(this.moveDirection);
		}

		// Token: 0x06000681 RID: 1665 RVA: 0x0003ABD4 File Offset: 0x00038DD4
		public virtual void Rotate()
		{
			if (this.platformAngularVelocity != Vector3.zero)
			{
				base.transform.rotation = Quaternion.Euler(this.platformAngularVelocity) * base.transform.rotation;
			}
			float num = base.GetAngleFromForward(this.GetForwardDirection());
			if (this.userControl.state.move == Vector3.zero)
			{
				num *= (1.01f - Mathf.Abs(num) / 180f) * this.stationaryTurnSpeedMlp;
			}
			base.RigidbodyRotateAround(this.characterAnimation.GetPivotPoint(), base.transform.up, num * Time.deltaTime * this.turnSpeed);
		}

		// Token: 0x06000682 RID: 1666 RVA: 0x0003AC90 File Offset: 0x00038E90
		public Vector3 GetForwardDirection()
		{
			bool flag = this.userControl.state.move != Vector3.zero;
			CharacterThirdPerson.MoveMode moveMode = this.moveMode;
			if (moveMode != CharacterThirdPerson.MoveMode.Directional)
			{
				if (moveMode != CharacterThirdPerson.MoveMode.Strafe)
				{
					return Vector3.zero;
				}
				if (flag)
				{
					return this.userControl.state.lookPos - this.r.position;
				}
				return (!this.lookInCameraDirection) ? base.transform.forward : (this.userControl.state.lookPos - this.r.position);
			}
			else
			{
				if (flag)
				{
					return this.userControl.state.move;
				}
				return (!this.lookInCameraDirection) ? base.transform.forward : (this.userControl.state.lookPos - this.r.position);
			}
		}

		// Token: 0x06000683 RID: 1667 RVA: 0x0003AD8C File Offset: 0x00038F8C
		public virtual bool Jump()
		{
			if (!this.userControl.state.jump)
			{
				return false;
			}
			if (this.userControl.state.crouch)
			{
				return false;
			}
			if (!this.characterAnimation.animationGrounded)
			{
				return false;
			}
			if (Time.time < this.lastAirTime + this.jumpRepeatDelayTime)
			{
				return false;
			}
			this.onGround = false;
			this.jumpEndTime = Time.time + 0.1f;
			Vector3 velocity = this.userControl.state.move * this.airSpeed;
			this.r.velocity = velocity;
			this.r.velocity += base.transform.up * this.jumpPower;
			return true;
		}

		// Token: 0x06000684 RID: 1668 RVA: 0x0003AE60 File Offset: 0x00039060
		public void GroundCheck()
		{
			Vector3 b = Vector3.zero;
			this.platformAngularVelocity = Vector3.zero;
			float num = 0f;
			this.hit = this.GetSpherecastHit();
			this.normal = base.transform.up;
			this.groundDistance = this.r.position.y - this.hit.point.y;
			bool flag = Time.time > this.jumpEndTime && this.r.velocity.y < this.jumpPower * 0.5f;
			if (flag)
			{
				bool onGround = this.onGround;
				this.onGround = false;
				float num2 = onGround ? this.airborneThreshold : (this.airborneThreshold * 0.5f);
				Vector3 velocity = this.r.velocity;
				velocity.y = 0f;
				float magnitude = velocity.magnitude;
				if (this.groundDistance < num2)
				{
					num = this.groundStickyEffect * magnitude * num2;
					if (this.hit.rigidbody != null)
					{
						b = this.hit.rigidbody.GetPointVelocity(this.hit.point);
						this.platformAngularVelocity = Vector3.Project(this.hit.rigidbody.angularVelocity, base.transform.up);
					}
					this.onGround = true;
				}
			}
			this.platformVelocity = Vector3.Lerp(this.platformVelocity, b, Time.deltaTime * this.platformFriction);
			this.stickyForce = num;
			if (!this.onGround)
			{
				this.lastAirTime = Time.time;
			}
		}

		// Token: 0x040005C1 RID: 1473
		[Header("References")]
		public CharacterAnimationBase characterAnimation;

		// Token: 0x040005C2 RID: 1474
		public UserControlThirdPerson userControl;

		// Token: 0x040005C3 RID: 1475
		public CameraController cam;

		// Token: 0x040005C4 RID: 1476
		[Header("Movement")]
		public CharacterThirdPerson.MoveMode moveMode;

		// Token: 0x040005C5 RID: 1477
		public bool smoothPhysics = true;

		// Token: 0x040005C6 RID: 1478
		public float smoothAccelerationTime = 0.2f;

		// Token: 0x040005C7 RID: 1479
		public float linearAccelerationSpeed = 3f;

		// Token: 0x040005C8 RID: 1480
		public float platformFriction = 7f;

		// Token: 0x040005C9 RID: 1481
		public float groundStickyEffect = 4f;

		// Token: 0x040005CA RID: 1482
		public float maxVerticalVelocityOnGround = 3f;

		// Token: 0x040005CB RID: 1483
		public float velocityToGroundTangentWeight;

		// Token: 0x040005CC RID: 1484
		[Header("Rotation")]
		public bool lookInCameraDirection;

		// Token: 0x040005CD RID: 1485
		public float turnSpeed = 5f;

		// Token: 0x040005CE RID: 1486
		public float stationaryTurnSpeedMlp = 1f;

		// Token: 0x040005CF RID: 1487
		[Header("Jumping and Falling")]
		public float airSpeed = 6f;

		// Token: 0x040005D0 RID: 1488
		public float airControl = 2f;

		// Token: 0x040005D1 RID: 1489
		public float jumpPower = 12f;

		// Token: 0x040005D2 RID: 1490
		public float jumpRepeatDelayTime;

		// Token: 0x040005D3 RID: 1491
		[Header("Wall Running")]
		[SerializeField]
		public LayerMask wallRunLayers;

		// Token: 0x040005D4 RID: 1492
		public float wallRunMaxLength = 1f;

		// Token: 0x040005D5 RID: 1493
		public float wallRunMinMoveMag = 0.6f;

		// Token: 0x040005D6 RID: 1494
		public float wallRunMinVelocityY = -1f;

		// Token: 0x040005D7 RID: 1495
		public float wallRunRotationSpeed = 1.5f;

		// Token: 0x040005D8 RID: 1496
		public float wallRunMaxRotationAngle = 70f;

		// Token: 0x040005D9 RID: 1497
		public float wallRunWeightSpeed = 5f;

		// Token: 0x040005DA RID: 1498
		[Header("Crouching")]
		public float crouchCapsuleScaleMlp = 0.6f;

		// Token: 0x040005DB RID: 1499
		public CharacterThirdPerson.AnimState animState = default(CharacterThirdPerson.AnimState);

		// Token: 0x040005DC RID: 1500
		public Vector3 moveDirection;

		// Token: 0x040005DD RID: 1501
		public Animator animator;

		// Token: 0x040005DE RID: 1502
		public Vector3 normal;

		// Token: 0x040005DF RID: 1503
		public Vector3 platformVelocity;

		// Token: 0x040005E0 RID: 1504
		public Vector3 platformAngularVelocity;

		// Token: 0x040005E1 RID: 1505
		public RaycastHit hit;

		// Token: 0x040005E2 RID: 1506
		public float jumpLeg;

		// Token: 0x040005E3 RID: 1507
		public float jumpEndTime;

		// Token: 0x040005E4 RID: 1508
		public float forwardMlp;

		// Token: 0x040005E5 RID: 1509
		public float groundDistance;

		// Token: 0x040005E6 RID: 1510
		public float lastAirTime;

		// Token: 0x040005E7 RID: 1511
		public float stickyForce;

		// Token: 0x040005E8 RID: 1512
		public Vector3 wallNormal = Vector3.up;

		// Token: 0x040005E9 RID: 1513
		public Vector3 moveDirectionVelocity;

		// Token: 0x040005EA RID: 1514
		public float wallRunWeight;

		// Token: 0x040005EB RID: 1515
		public float lastWallRunWeight;

		// Token: 0x040005EC RID: 1516
		public Vector3 fixedDeltaPosition;

		// Token: 0x040005ED RID: 1517
		public Quaternion fixedDeltaRotation;

		// Token: 0x040005EE RID: 1518
		public bool fixedFrame;

		// Token: 0x040005EF RID: 1519
		public float wallRunEndTime;

		// Token: 0x020000E0 RID: 224
		[Serializable]
		public enum MoveMode
		{
			// Token: 0x040005F2 RID: 1522
			Directional,
			// Token: 0x040005F3 RID: 1523
			Strafe
		}

		// Token: 0x020000E1 RID: 225
		public struct AnimState
		{
			// Token: 0x040005F4 RID: 1524
			public Vector3 moveDirection;

			// Token: 0x040005F5 RID: 1525
			public bool jump;

			// Token: 0x040005F6 RID: 1526
			public bool crouch;

			// Token: 0x040005F7 RID: 1527
			public bool onGround;

			// Token: 0x040005F8 RID: 1528
			public bool isStrafing;

			// Token: 0x040005F9 RID: 1529
			public float yVelocity;
		}
	}
}
